﻿# -*- coding:UTF-8 -*-
#!/usr/bin/env python

import os , random , error500

from shorturl import model
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

from django.utils import simplejson as json

SHOULD_NOT_USE_PATH = ['shorturl']
RESULT_DEFINITION = {'shortUrlConflict':'短地址冲突，当前短地址指向：' , 'invalidOriginalUrl':'源地址错误' , \
                     'success':'生成成功，生成的短地址为：' , 'shortUrlExist':'该网址对应的短地址已存在，为：'}

class ShortURL(webapp.RequestHandler):
    def get(self):
        try:
            self.__startShort()
        except Exception , exceptions:
            error500.error500(self , ' %s %s' % (type(exceptions) , exceptions) , lang = self.request.get('viewAs') if self.request.get('viewAs') else "json")
    
    def post(self):
        try:
            self.__startShort()
        except Exception , exceptions:
            error500.error500(self , ' %s %s' % (type(exceptions) , exceptions) , lang = self.request.get('viewAs') if self.request.get('viewAs') else "json")
    
    def __startShort(self):
        message = ''
        shortUrl = self.request.get('shortUrl')
        originalUrl = self.request.get('originalUrl')
        viewAs = self.request.get('viewAs') if self.request.get('viewAs') else "json" ;
        background_path = os.path.join(os.path.dirname(__file__), 'background.html')
        if not (originalUrl or shortUrl) :
            self.response.out.write(template.render(background_path , None))
        else:
            result = self.__doShortUrl(shortUrl , originalUrl)
            if(viewAs == 'json'):
                if isinstance(result , tuple):
                    results = result[1] if result[1].startswith(('http://' , 'https://' , 'ftp://')) else ('http://%s/' % (self.request.headers['Host'])).__add__(result[1])
                    resultDic = {"status":result[0] , "result":results}
                else:
                    resultDic = {'error':result}
                jsonStr = json.dumps(resultDic)
                self.response.out.write(jsonStr)
            else:
                if isinstance(result , tuple):
                    results = result[1] if result[1].startswith(('http://' , 'https://' , 'ftp://')) else ('http://%s/' % (self.request.headers['Host'])).__add__(result[1])
                    message = '%s<a href="%s">%s</a>' % (RESULT_DEFINITION[result[0]] , results , results)
                else:
                    message = '%s' % RESULT_DEFINITION[result]
                message = {'msg' : message}
                self.response.out.write(template.render(background_path , message))
            
    
    def __doShortUrl(self , shortUrl , originalUrl):
        if shortUrl:
            conflictUrl = self.__check_short_conflict(shortUrl)
            if conflictUrl :
                if (conflictUrl == self.__check_original_url(originalUrl)) or (originalUrl == ''):
                    return ('shortUrlExist' , conflictUrl.encode('utf-8'))
                else :
                    return ('shortUrlConflict' , conflictUrl.encode('utf-8'))
            else:
                if not self.__check_original_url(originalUrl):
                    return 'invalidOriginalUrl'
                else:
                    originalUrl = self.__check_original_url(originalUrl)
                    self.__write_datastore(shortUrl , self.__check_original_url(originalUrl))
                    return ('success' , shortUrl.encode('utf-8'))
        else:
            originalUrl = self.__check_original_url(originalUrl)
            if originalUrl :
                shortUrlConfilctObj = self.__check_original_conflict(originalUrl)
                if shortUrlConfilctObj:
                    return ('shortUrlExist' , shortUrlConfilctObj.shortUrl.encode('utf-8'))
                shortUrl = self.__ceate_short_url()
                self.__write_datastore(shortUrl , self.__check_original_url(originalUrl))
                return ('success' , shortUrl.encode('utf-8'))
            else:
                return 'invalidOriginalUrl'
    
    def __ceate_short_url(self):
        short_str = ''
        while True :
            short_str = ''
            for i in xrange(5):
                while(True):
                    rand = random.randint(0 , 74)
                    if (0 <= rand <= 9) or (17 <= rand <= 42) or (49 <= rand <= 74):break
                short_str += chr(48 + rand)
            if not self.__check_short_conflict(short_str):
                break
        return short_str
    
    def __check_short_conflict(self , shortUrl):
        shortUrlObjs = db.GqlQuery("SELECT * FROM ShortUrl WHERE shortUrl = '%s'" % shortUrl)
        try:
            shortUrlObjs[0]
        except(IndexError):
            if shortUrl in SHOULD_NOT_USE_PATH:
                return True
            else:
                return False
        else:
            return shortUrlObjs[0].originalUrl
    
    def __check_original_conflict(self , originalUrl):
        shortUrlObjs = db.GqlQuery("SELECT * FROM ShortUrl WHERE originalUrl = '%s'" % originalUrl)
        try:
            shortUrlObjs[0]
        except(IndexError):
            return False
        else:
            return shortUrlObjs[0]
            
    def __check_original_url(self , originalUrl):
        if originalUrl:
            originalUrl = originalUrl if originalUrl.startswith(('http://' , 'https://' , 'ftp://')) else 'http://'.__add__(originalUrl)
            return originalUrl
        else:
            return False
    
    def __write_datastore(self , shortUrl , originalUrl):
        shortUrlObj = model.ShortUrl(shortUrl = shortUrl , originalUrl = originalUrl)
        shortUrlObj.put()

application = webapp.WSGIApplication(
                                     [('/shorturl.*' , ShortURL)] ,
                                     debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()